package javatunes;

public class sebpac
{
	public byte data[];
	public int pos;
	
	boolean debug=true;
	
	public final static int TINY=100;
	public final static int SMALL=5000;
	public final static int BIG=30000;
	
	public sebpac(int size) {
		data=new byte[size]; pos=0;
	}

	public sebpac(byte buf[]) {
		data=buf; pos=0;
	}
	
	public sebpac copy() {
		sebpac p=new sebpac(new byte[data.length]);
		for (int n=0; n<pos; n++) p.data[n]=data[n];
		p.pos=pos;
		return p;
	}
	
	public byte[] copydata() {
		byte buf[]=new byte[pos];
		for (int n=0; n<pos; n++) buf[n]=data[n];
		return buf;
	}
	
	/** Store 1 byte */
	public void p1(int val) {
		data[pos++]=(byte)val;
	}
	
	/** Store 2 bytes - big endian*/
	public void p2(int val) {
		data[pos++]=(byte)(val>>8);
		data[pos++]=(byte)(val);
	}
	
	/** Store 2 bytes - little endian*/
	public void p2i(int val) {
		data[pos++]=(byte)(val);
		data[pos++]=(byte)(val>>8);
	}
	
	/** Store 3 bytes - big endian*/
	public void p3(int val) {
		data[pos++]=(byte)(val>>16);
		data[pos++]=(byte)(val>>8);
		data[pos++]=(byte)(val);
	}
	
	/** Store 3 bytes - little endian*/
	public void p3i(int val) {
		data[pos++]=(byte)(val);
		data[pos++]=(byte)(val>>8);
		data[pos++]=(byte)(val>>16);
	}
	
	/** Store 4 bytes - big endian*/
	public void p4(int val) {
		data[pos++]=(byte)(val>>24);
		data[pos++]=(byte)(val>>16);
		data[pos++]=(byte)(val>>8);
		data[pos++]=(byte)(val);
	}
	
	/** Store 4 bytes - little endian*/
	public void p4i(int val) {
		data[pos++]=(byte)(val);
		data[pos++]=(byte)(val>>8);
		data[pos++]=(byte)(val>>16);
		data[pos++]=(byte)(val>>24);
	}
	
	/** Store 6 bytes - big endian*/
	public void p6(long val) {
		data[pos++]=(byte)(val>>40);
		data[pos++]=(byte)(val>>32);
		data[pos++]=(byte)(val>>24);
		data[pos++]=(byte)(val>>16);
		data[pos++]=(byte)(val>>8);
		data[pos++]=(byte)(val);
	}

	/** Store 7 bytes - big endian*/
	public void p7(long val) {
		data[pos++]=(byte)(val>>48);
		data[pos++]=(byte)(val>>40);
		data[pos++]=(byte)(val>>32);
		data[pos++]=(byte)(val>>24);
		data[pos++]=(byte)(val>>16);
		data[pos++]=(byte)(val>>8);
		data[pos++]=(byte)(val);
	}

	/** Store 8 bytes - big endian*/
	public void p8(long val) {
		data[pos++]=(byte)(val>>56);
		data[pos++]=(byte)(val>>48);
		data[pos++]=(byte)(val>>40);
		data[pos++]=(byte)(val>>32);
		data[pos++]=(byte)(val>>24);
		data[pos++]=(byte)(val>>16);
		data[pos++]=(byte)(val>>8);
		data[pos++]=(byte)(val);
	}
		
	/** Store 8 bytes - little endian*/
	public void p8i(long val) {
		data[pos++]=(byte)(val);
		data[pos++]=(byte)(val>>8);
		data[pos++]=(byte)(val>>16);
		data[pos++]=(byte)(val>>24);
		data[pos++]=(byte)(val>>32);
		data[pos++]=(byte)(val>>40);
		data[pos++]=(byte)(val>>48);
		data[pos++]=(byte)(val>>56);
	}
	
	public void px(long val, int b) {
		b--;
		if (b<0 || b>7) {
			if (debug) throw new IllegalArgumentException("Illegal number of bytes requested in px() - must be between 1 and 8!");
			else throw new IllegalArgumentException();
		}
		int sh=b*8;
		while (sh>=0) { data[pos++]=(byte)(val>>sh); sh-=8; }
	}
	
	public void pstr(String val) {
		pdata(val.getBytes(),0,val.length());
		data[pos++]=0;
	}
			
	public void pdata(byte b[], int off, int size) {
		for (int n=off; n<off+size; n++) data[pos++]=b[n];
	}
	
	public void pad(int max) {
		while (pos<max) data[pos++]=0;
	}
	
	public void moveupdata(int drop) {
		if (drop>=pos) {pos=0; return;}
		for (int n=drop; n<pos; n++) data[n-drop]=data[n];
		pos-=drop;
	}
			
	public void psize4(int size) {
		data[pos-size-4]=(byte)(size>>24);
		data[pos-size-3]=(byte)(size>>16);
		data[pos-size-2]=(byte)(size>>8);
		data[pos-size-1]=(byte)(size);
	}
	
	public void psize2(int size) {
		data[pos-size-2]=(byte)(size>>8);
		data[pos-size-1]=(byte)(size);
	}
	
	public void psize1(int size) {
		data[pos-size-1]=(byte)(size);
	}
	
	public int g1() {
		return data[pos++]&255;
	}
	
	public byte g1b() {
		return data[pos++];
	}
	
	public int g2() {
		pos+=2;
		return ((data[pos-2]&255)<<8)+(data[pos-1]&255);
	}
	
	public int g2i() {
		pos+=2;
		return ((data[pos-1]&255)<<8)+(data[pos-2]&255);
	}
	
	public int g2b() {
		pos+=2;
		int val=((data[pos-2]&255)<<8)+(data[pos-1]&255);
		if (val>32767) val-=65536;
		return val;
	}
	
	public int g3() {
		pos+=3;
		return ((data[pos-3]&255)<<16)+((data[pos-2]&255)<<8)+(data[pos-1]&255);
	}
	
	public int g3i() {
		pos+=3;
		return ((data[pos-1]&255)<<16)+((data[pos-2]&255)<<8)+(data[pos-3]&255);
	}
	
	public int g4() {
		pos+=4;
		return ((data[pos-4]&255)<<24)+((data[pos-3]&255)<<16)+((data[pos-2]&255)<<8)+(data[pos-1]&255);
	}
	
	public String gnstr(int n) {
		byte[] temp=new byte[n];
		gdata(temp,0,n);
		return new String(temp);
	}
	
	public String gnstrdata(int n) {
		String temp="";
		for (int i=0;i<n;i++) { temp+=(char)data[pos++];pos++; i++;}
		return new String(temp);
	}
	
	public int g4i() {
		pos+=4;
		return ((data[pos-1]&255)<<24)+((data[pos-2]&255)<<16)+((data[pos-3]&255)<<8)+(data[pos-4]&255);
	}
	
	public long g6() {
		long top=g2()&0xffffffffL;
		long base=g4()&0xffffffffL;
		return (top<<32)+base;
	}
	
	public long g8() {
		long top=g4()&0xffffffffL;
		long base=g4()&0xffffffffL;
		return (top<<32)+base;
	}
	
	public long g7() {
		long top=g3()&0xffffffffL;
		long base=g4()&0xffffffffL;
		return (top<<32)+base;
	}
	
	public long g8i() {
		long base=g4i()&0xffffffffL;
		long top=g4i()&0xffffffffL;
		return (top<<32)+base;
	}
	
	public long gx(int b) {
		b--;
		if (b<0 || b>7) {
			if (debug) throw new IllegalArgumentException("Illegal number of bytes requested in gx() - must be between 1 and 8!");
			else throw new IllegalArgumentException();
		}
		int sh=b*8;
		long v=0;
		while (sh>=0) { v|=(((long)data[pos++])&0xff)<<sh; sh-=8; }
		return v;
	}
	
	public String gstr() {
		int start=pos; while (data[pos++]!=0);
		int length=pos-start;
		pos-=length;
		byte[] temp=new byte[length];
		gdata(temp,0,length);
		return new String(temp).substring(0,temp.length-1);
	}
	
	public void gdata(byte b[], int off, int size) {
		for (int n=off; n<off+size; n++) b[n]=data[pos++];
		
	}
	
}
